home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / other / jikes / src / definite.cpp < prev    next >
C/C++ Source or Header  |  1999-05-14  |  74KB  |  1,979 lines

  1. // $Id: definite.cpp,v 1.5 1999/03/10 19:59:21 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include "config.h"
  11. #include <assert.h>
  12. #include <stdio.h>
  13. #include "semantic.h"
  14.  
  15. DefiniteAssignmentSet *Semantic::DefiniteExpression(AstExpression *expr, BitSet &set)
  16. {
  17.     DefiniteAssignmentSet *definite = NULL;
  18.  
  19.     //
  20.     // Is the expression a constant expression of type boolean?
  21.     // Recall that a constant expression may not contain an 
  22.     // assignment statement.
  23.     //
  24.     if (expr -> IsConstant() && expr -> Type() == control.boolean_type)
  25.     {
  26.         definite = new DefiniteAssignmentSet(universe -> Size());
  27.         IntLiteralValue *result = (IntLiteralValue *) expr -> value;
  28.         if (result -> value)
  29.         {
  30.             definite -> true_set  = set;
  31.             definite -> false_set = *universe;
  32.         }
  33.         else 
  34.         {
  35.             definite -> true_set  = *universe;
  36.             definite -> false_set = set;
  37.         }
  38.     }
  39.     else if (expr -> symbol != control.no_type)
  40.         definite = (this ->* DefiniteExpr[expr -> kind])(expr, set);
  41.  
  42.     return definite;
  43. }
  44.  
  45.  
  46. DefiniteAssignmentSet *Semantic::DefiniteSimpleName(AstExpression *expression, BitSet &set)
  47. {
  48.     AstSimpleName *simple_name = (AstSimpleName *) expression;
  49.  
  50.     if (simple_name -> resolution_opt)
  51.         return DefiniteExpression(simple_name -> resolution_opt, set);
  52.  
  53.     //
  54.     // Some simple names are undefined. e.g., the simple name in a method call.
  55.     //
  56.     VariableSymbol *variable = (simple_name -> symbol ? simple_name -> symbol -> VariableCast() : (VariableSymbol *) NULL);
  57.     if (variable && (variable -> IsLocal(ThisMethod()) || variable -> IsFinal(ThisType())))
  58.     {
  59.         if (! set[variable -> LocalVariableIndex()])
  60.         {
  61.             ReportSemError(SemanticError::VARIABLE_NOT_DEFINITELY_ASSIGNED,
  62.                            simple_name -> identifier_token,
  63.                            simple_name -> identifier_token,
  64.                            variable -> Name());
  65.  
  66.             if (variable -> IsLocal(ThisMethod())) // to avoid cascading errors!
  67.                 set.AddElement(variable -> LocalVariableIndex());
  68.         }
  69.     }
  70.  
  71.     return (DefiniteAssignmentSet *) NULL;
  72. }
  73.  
  74.  
  75. DefiniteAssignmentSet *Semantic::DefiniteArrayAccess(AstExpression *expression, BitSet &set)
  76. {
  77.     AstArrayAccess *array_access = (AstArrayAccess *) expression;
  78.  
  79.     DefiniteAssignmentSet *after_base = DefiniteExpression(array_access -> base, set);
  80.     if (after_base) // if this is true then something is wrong
  81.     {
  82.         set = after_base -> true_set * after_base -> false_set;
  83.         delete after_base;
  84.     }
  85.  
  86.     DefiniteAssignmentSet *after_expr = DefiniteExpression(array_access -> expression, set);
  87.     if (after_expr) // if this is true then something is wrong
  88.     {
  89.         set = after_expr -> true_set * after_expr -> false_set;
  90.         delete after_expr;
  91.     }
  92.  
  93.     return (DefiniteAssignmentSet *) NULL;
  94. }
  95.  
  96.  
  97. DefiniteAssignmentSet *Semantic::DefiniteMethodInvocation(AstExpression *expression, BitSet &set)
  98. {
  99.     AstMethodInvocation *method_call = (AstMethodInvocation *) expression;
  100.  
  101.     DefiniteAssignmentSet *after_method = DefiniteExpression(method_call -> method, set);
  102.     if (after_method)
  103.     {
  104.         set = after_method -> true_set * after_method -> false_set;
  105.         delete after_method;
  106.     }
  107.  
  108.     for (int i = 0; i < method_call -> NumArguments(); i++)
  109.     {
  110.         AstExpression *expr = method_call -> Argument(i);
  111.         DefiniteAssignmentSet *after_expr = DefiniteExpression(expr, set);
  112.         if (after_expr)
  113.         {
  114.             set = after_expr -> true_set * after_expr -> false_set;
  115.             delete after_expr;
  116.         }
  117.     }
  118.  
  119.     return (DefiniteAssignmentSet *) NULL;
  120. }
  121.  
  122.  
  123. DefiniteAssignmentSet *Semantic::DefiniteClassInstanceCreationExpression(AstExpression *expression, BitSet &set)
  124. {
  125.     AstClassInstanceCreationExpression *class_creation = (AstClassInstanceCreationExpression *) expression;
  126.  
  127.     if (class_creation -> base_opt)
  128.     {
  129.         DefiniteAssignmentSet *after_expr = DefiniteExpression(class_creation -> base_opt, set);
  130.         if (after_expr)
  131.         {
  132.             set = after_expr -> true_set * after_expr -> false_set;
  133.             delete after_expr;
  134.         }
  135.     }
  136.  
  137.     for (int i = 0; i < class_creation -> NumLocalArguments(); i++)
  138.     {
  139.         AstExpression *expr = class_creation -> LocalArgument(i);
  140.         DefiniteAssignmentSet *after_expr = DefiniteExpression(expr, set);
  141.         if (after_expr)
  142.         {
  143.             set = after_expr -> true_set * after_expr -> false_set;
  144.             delete after_expr;
  145.         }
  146.     }
  147.  
  148.     for (int k = 0; k < class_creation -> NumArguments(); k++)
  149.     {
  150.         AstExpression *expr = class_creation -> Argument(k);
  151.         DefiniteAssignmentSet *after_expr = DefiniteExpression(expr, set);
  152.         if (after_expr)
  153.         {
  154.             set = after_expr -> true_set * after_expr -> false_set;
  155.             delete after_expr;
  156.         }
  157.     }
  158.  
  159.     return (DefiniteAssignmentSet *) NULL;
  160. }
  161.  
  162.  
  163. DefiniteAssignmentSet *Semantic::DefiniteArrayCreationExpression(AstExpression *expression, BitSet &set)
  164. {
  165.     AstArrayCreationExpression *array_creation = (AstArrayCreationExpression *) expression;
  166.  
  167.     for (int i = 0; i < array_creation -> NumDimExprs(); i++)
  168.     {
  169.         AstDimExpr *dim_expr = array_creation -> DimExpr(i);
  170.         DefiniteAssignmentSet *after_expr = DefiniteExpression(dim_expr -> expression, set);
  171.         if (after_expr)
  172.         {
  173.             set = after_expr -> true_set * after_expr -> false_set;
  174.             delete after_expr;
  175.         }
  176.     }
  177.  
  178.     if (array_creation -> array_initializer_opt)
  179.         DefiniteArrayInitializer(array_creation -> array_initializer_opt);
  180.  
  181.     return (DefiniteAssignmentSet *) NULL;
  182. }
  183.  
  184.  
  185. inline VariableSymbol *Semantic::DefiniteFinal(AstFieldAccess *field_access)
  186. {
  187.     if (field_access -> resolution_opt)
  188.         field_access = field_access -> resolution_opt -> FieldAccessCast();
  189.  
  190.     if (field_access)
  191.     {
  192.         VariableSymbol *variable = (field_access -> symbol ? field_access -> symbol -> VariableCast() : (VariableSymbol *) NULL);
  193.         if (variable && variable -> IsFinal(ThisType()))
  194.         {
  195.             if (variable -> ACC_STATIC()) // there is exactly one copy of a static variable, so, it's always the right one.
  196.                 return variable;
  197.         
  198.             AstFieldAccess *sub_field_access = field_access -> base -> FieldAccessCast();
  199.             if (field_access -> base -> ThisExpressionCast() || (sub_field_access && sub_field_access -> IsThisAccess()))
  200.                 return variable;
  201.         }
  202.     }
  203.  
  204.     return NULL;
  205. }
  206.  
  207.  
  208. DefiniteAssignmentSet *Semantic::DefinitePLUSPLUSOrMINUSMINUS(AstExpression *expr, BitSet &set)
  209. {
  210.     DefiniteAssignmentSet *definite = DefiniteExpression(expr, set);
  211.     if (definite) // if this is true then something is wrong
  212.     {
  213.         set = definite -> true_set * definite -> false_set;
  214.         delete definite;
  215.     }
  216.  
  217.     VariableSymbol *variable = NULL;
  218.     if (! expr -> ArrayAccessCast()) // some kind of name
  219.     {
  220.         MethodSymbol *read_method = NULL;
  221.         AstSimpleName *simple_name = expr -> SimpleNameCast();
  222.         if (simple_name)
  223.         {
  224.             if (simple_name -> resolution_opt)
  225.                read_method = simple_name -> resolution_opt -> symbol -> MethodCast();
  226.         }
  227.         else
  228.         {
  229.             AstFieldAccess *field_access = expr -> FieldAccessCast();
  230. assert(field_access);
  231.             if (field_access -> resolution_opt)
  232.                 read_method = field_access -> resolution_opt -> symbol -> MethodCast();
  233.         }
  234.  
  235.         variable = (read_method ? (VariableSymbol *) read_method -> accessed_member : expr -> symbol -> VariableCast());
  236.     }
  237.  
  238.     //
  239.     // If we have a variable and it is final then...
  240.     //
  241.     if (variable && variable -> ACC_FINAL())
  242.     {
  243.         ReportSemError(SemanticError::TARGET_VARIABLE_IS_FINAL,
  244.                        expr -> LeftToken(),
  245.                        expr -> RightToken(),
  246.                        variable -> Name());
  247.  
  248.         if (variable -> IsFinal(ThisType())) // if the final variable in contained in this type, then mark it assigned
  249.             possibly_assigned_finals -> AddElement(variable -> LocalVariableIndex());
  250.     }
  251.  
  252.     return (DefiniteAssignmentSet *) NULL;
  253. }
  254.  
  255.  
  256. DefiniteAssignmentSet *Semantic::DefinitePostUnaryExpression(AstExpression *expression, BitSet &set)
  257. {
  258.     AstPostUnaryExpression *postfix_expression = (AstPostUnaryExpression *) expression;
  259.     return DefinitePLUSPLUSOrMINUSMINUS(postfix_expression -> expression, set);
  260. }
  261.  
  262.  
  263. DefiniteAssignmentSet *Semantic::DefiniteNOT(AstExpression *expr, BitSet &set)
  264. {
  265.     DefiniteAssignmentSet *after_expr = DefiniteExpression(expr, set);
  266.     if (after_expr) // is the expression is a complex boolean expression?
  267.     {
  268.         BitSet temp(after_expr -> true_set);
  269.         after_expr -> true_set = after_expr -> false_set;
  270.         after_expr -> false_set = temp;
  271.     }
  272.  
  273.     return after_expr;
  274. }
  275.  
  276.  
  277. //
  278. // The default pre unary operators are +, -, and ~.
  279. // As these operators are not applicable to boolean expressions,
  280. // we do not need to invoke DefiniteExpression to process them.
  281. //
  282. DefiniteAssignmentSet *Semantic::DefiniteDefaultPreUnaryExpression(AstExpression *expr, BitSet &set)
  283. {
  284.     return (this ->* DefiniteExpr[expr -> kind])(expr, set);
  285. }
  286.  
  287.  
  288. DefiniteAssignmentSet *Semantic::DefinitePreUnaryExpression(AstExpression *expression, BitSet &set)
  289. {
  290.     AstPreUnaryExpression *prefix_expression = (AstPreUnaryExpression *) expression;
  291.     return (this ->* DefinitePreUnaryExpr[prefix_expression -> pre_unary_tag])(prefix_expression -> expression, set);
  292. }
  293.  
  294.  
  295. DefiniteAssignmentSet *Semantic::DefiniteAssignmentAND(TypeSymbol *type,
  296.                                                        BitSet *before_right,
  297.                                                        BitSet &set,
  298.                                                        DefiniteAssignmentSet *after_left,
  299.                                                        DefiniteAssignmentSet *after_right)
  300. {
  301.     if (after_left || after_right) // one of the subexpressions is a complex boolean expression 
  302.     {
  303.         if (! after_left)
  304.         {
  305.             after_left = new DefiniteAssignmentSet(universe -> Size());
  306.             after_left -> true_set = *before_right;
  307.             after_left -> false_set = *before_right;
  308.         }
  309.  
  310.         if (! after_right)
  311.         {
  312.             after_right = new DefiniteAssignmentSet(universe -> Size());
  313.             after_right -> true_set = set;
  314.             after_right -> false_set = set;
  315.         }
  316.  
  317.         after_left -> true_set += after_right -> true_set;   // definitely assigned after left when true and after right when true
  318.         after_left -> false_set *= after_right -> false_set; // definitely assigned after left when false and after right when false
  319.         after_right -> true_set *= after_right -> false_set; // definitely assigned after right
  320.         after_left -> false_set += after_right -> true_set;
  321.  
  322.         delete after_right;
  323.     }
  324.  
  325.     delete before_right; // nothing happens if before_right is null
  326.  
  327.     return after_left;
  328. }
  329.  
  330.  
  331. DefiniteAssignmentSet *Semantic::DefiniteAssignmentIOR(TypeSymbol *type,
  332.                                                        BitSet *before_right, 
  333.                                                        BitSet &set,
  334.                                                        DefiniteAssignmentSet *after_left,
  335.                                                        DefiniteAssignmentSet *after_right)
  336. {
  337.     if (after_left || after_right) // one of the subexpressions is a complex boolean expression 
  338.     {
  339.         if (! after_left)
  340.         {
  341.             after_left = new DefiniteAssignmentSet(universe -> Size());
  342.             after_left -> true_set = *before_right;
  343.             after_left -> false_set = *before_right;
  344.         }
  345.  
  346.         if (! after_right)
  347.         {
  348.             after_right = new DefiniteAssignmentSet(universe -> Size());
  349.             after_right -> true_set = set;
  350.             after_right -> false_set = set;
  351.         }
  352.  
  353.         after_left -> true_set *= after_right -> true_set;   // after a when true and after b when true
  354.         after_right -> true_set *= after_right -> false_set; // definitely assigned after b
  355.         after_left -> true_set += after_right -> true_set;
  356.         after_left -> false_set += after_right -> false_set; // after a when false or after b when false
  357.  
  358.         delete after_right;
  359.     }
  360.  
  361.     delete before_right; // nothing happens if before_right is null
  362.  
  363.     return after_left;
  364. }
  365.  
  366.  
  367. DefiniteAssignmentSet *Semantic::DefiniteAssignmentXOR(TypeSymbol *type,
  368.                                                        BitSet *before_right,
  369.                                                        BitSet &set,
  370.                                                        DefiniteAssignmentSet *after_left,
  371.                                                        DefiniteAssignmentSet *after_right)
  372. {
  373.     DefiniteAssignmentSet *definite = NULL;
  374.  
  375.     if (after_left || after_right) // one of the subexpressions is a complex boolean expression 
  376.     {
  377.         definite = new DefiniteAssignmentSet(universe -> Size());
  378.  
  379.         if (! after_left)
  380.         {
  381.             after_left = new DefiniteAssignmentSet(universe -> Size());
  382.             after_left -> true_set = *before_right;
  383.             after_left -> false_set = *before_right;
  384.         }
  385.  
  386.         if (! after_right)
  387.         {
  388.             after_right = new DefiniteAssignmentSet(universe -> Size());
  389.             after_right -> true_set = set;
  390.             after_right -> false_set = set;
  391.         }
  392.  
  393.         //
  394.         // compute definitely assigned after right.
  395.         //
  396.         definite -> true_set = definite -> false_set = (after_right -> true_set * after_right -> false_set);
  397.         
  398.         //
  399.         // compute definitely assigned after left when true and after right when true
  400.         // compute definitely assigned after left when false and after right when false
  401.         // add the union of these two sets to true_set;
  402.         //
  403.         definite -> true_set += (after_left -> true_set * after_right -> true_set)
  404.                               + (after_left -> false_set * after_right -> false_set);
  405.         //
  406.         // compute definitely assigned after left when true and after right when false
  407.         // compute definitely assigned after left when false and after right when true
  408.         // add the union of these two sets to false_set;
  409.         //
  410.         definite -> false_set += (after_left -> true_set * after_right -> false_set)
  411.                                + (after_left -> false_set * after_right -> true_set);
  412.  
  413.         delete after_left;
  414.         delete after_right;
  415.     }
  416.  
  417.     delete before_right;  // nothing happens if before_right is NULL
  418.  
  419.     return definite;
  420. }
  421.  
  422.  
  423. DefiniteAssignmentSet *Semantic::DefiniteAND(AstBinaryExpression *expr, BitSet &set)
  424. {
  425.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  426.     BitSet *before_right = NULL;
  427.     if (after_left)
  428.          set = after_left -> true_set * after_left -> false_set;
  429.     else before_right = new BitSet(set);
  430.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  431.  
  432.     return DefiniteAssignmentAND(expr -> left_expression -> Type(), before_right, set, after_left, after_right);
  433. }
  434.  
  435.  
  436. DefiniteAssignmentSet *Semantic::DefiniteIOR(AstBinaryExpression *expr, BitSet &set)
  437. {
  438.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  439.     BitSet *before_right = NULL;
  440.     if (after_left)
  441.          set = after_left -> true_set * after_left -> false_set;
  442.     else before_right = new BitSet(set);
  443.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  444.  
  445.     return DefiniteAssignmentIOR(expr -> left_expression -> Type(), before_right, set, after_left, after_right);
  446. }
  447.  
  448.  
  449. DefiniteAssignmentSet *Semantic::DefiniteXOR(AstBinaryExpression *expr, BitSet &set)
  450. {
  451.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  452.     BitSet *before_right = NULL;
  453.     if (after_left)
  454.          set = after_left -> true_set * after_left -> false_set;
  455.     else before_right = new BitSet(set);
  456.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  457.  
  458.     return DefiniteAssignmentXOR(expr -> left_expression -> Type(), before_right, set, after_left, after_right);
  459. }
  460.  
  461.  
  462. DefiniteAssignmentSet *Semantic::DefiniteAND_AND(AstBinaryExpression *expr, BitSet &set)
  463. {
  464.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  465.     BitSet *before_right = NULL;
  466.     if (after_left)
  467.          set = after_left -> true_set;
  468.     else before_right = new BitSet(set);
  469.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  470.  
  471.     if (after_left)
  472.     {
  473.         if (after_right)
  474.         {
  475.             after_left -> true_set += after_right -> true_set;
  476.             after_left -> false_set *= after_right -> false_set;
  477.             delete after_right;
  478.         }
  479.         else
  480.         {
  481.             after_left -> true_set += set;
  482.             after_left -> false_set *= set;
  483.         }
  484.  
  485.         after_right = after_left;
  486.     }
  487.     else
  488.     {
  489.         if (! after_right)
  490.         {
  491.             after_right = new DefiniteAssignmentSet(universe -> Size());
  492.  
  493.             after_right -> true_set = set;
  494.             after_right -> false_set = set;
  495.         }
  496.         after_right -> true_set += *before_right;
  497.         after_right -> false_set *= *before_right;
  498.  
  499.         delete before_right;
  500.     }
  501.  
  502.     return after_right;
  503. }
  504.  
  505.  
  506. DefiniteAssignmentSet *Semantic::DefiniteOR_OR(AstBinaryExpression *expr, BitSet &set)
  507. {
  508.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  509.     BitSet *before_right = NULL;
  510.     if (after_left)
  511.          set = after_left -> false_set;
  512.     else before_right = new BitSet(set);
  513.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  514.  
  515.     if (after_left)
  516.     {
  517.         if (after_right)
  518.         {
  519.             after_left -> true_set *= after_right -> true_set;
  520.             after_left -> false_set += after_right -> false_set;
  521.             delete after_right;
  522.         }
  523.         else
  524.         {
  525.             after_left -> true_set *= set;
  526.             after_left -> false_set += set;
  527.         }
  528.  
  529.         after_right = after_left;
  530.     }
  531.     else
  532.     {
  533.         if (! after_right)
  534.         {
  535.             after_right = new DefiniteAssignmentSet(universe -> Size());
  536.  
  537.             after_right -> true_set = set;
  538.             after_right -> false_set = set;
  539.         }
  540.         after_right -> true_set *= *before_right;
  541.         after_right -> false_set += *before_right;
  542.  
  543.         delete before_right;
  544.     }
  545.  
  546.     return after_right;
  547. }
  548.  
  549.  
  550. DefiniteAssignmentSet *Semantic::DefiniteEQUAL_EQUAL(AstBinaryExpression *expr, BitSet &set)
  551. {
  552.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  553.     BitSet *before_right = NULL;
  554.     if (after_left)
  555.          set = after_left -> true_set * after_left -> false_set;
  556.     else before_right = new BitSet(set);
  557.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  558.  
  559.     DefiniteAssignmentSet *definite = NULL;
  560.  
  561.     if (after_left || after_right) // one of the subexpressions is a complex boolean expression 
  562.     {
  563.         definite = new DefiniteAssignmentSet(universe -> Size());
  564.  
  565.         if (! after_left)
  566.         {
  567.             after_left = new DefiniteAssignmentSet(universe -> Size());
  568.             after_left -> true_set = *before_right;
  569.             after_left -> false_set = *before_right;
  570.         }
  571.  
  572.         if (! after_right)
  573.         {
  574.             after_right = new DefiniteAssignmentSet(universe -> Size());
  575.             after_right -> true_set = set;
  576.             after_right -> false_set = set;
  577.         }
  578.  
  579.         //
  580.         // compute definitely assigned after right.
  581.         //
  582.         definite -> true_set = definite -> false_set = (after_right -> true_set * after_right -> false_set);
  583.  
  584.         //
  585.         // compute definitely assigned after left when true and after right when false
  586.         // compute definitely assigned after left when false and after right when true
  587.         // and add their union to true_set
  588.         //
  589.         definite -> true_set += (after_left -> true_set * after_right -> false_set)
  590.                               + (after_left -> false_set * after_right -> true_set);
  591.  
  592.         //
  593.         // compute definitely assigned after left when true and after right when true
  594.         // compute definitely assigned after left when false and after right when false
  595.         // and add their union to false_set
  596.         //
  597.         definite -> false_set += (after_left -> true_set * after_right -> true_set)
  598.                                + (after_left -> false_set * after_right -> false_set);
  599.  
  600.         delete after_left;
  601.         delete after_right;
  602.     }
  603.  
  604.     delete before_right; // nothing happens if before_right is NULL
  605.  
  606.     return definite;
  607. }
  608.  
  609.  
  610. DefiniteAssignmentSet *Semantic::DefiniteNOT_EQUAL(AstBinaryExpression *expr, BitSet &set)
  611. {
  612.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  613.     BitSet *before_right = NULL;
  614.     if (after_left)
  615.          set = after_left -> true_set * after_left -> false_set;
  616.     else before_right = new BitSet(set);
  617.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  618.  
  619.     //
  620.     // NOT_EQUAL has same definite assignment rules as XOR
  621.     //
  622.     return DefiniteAssignmentXOR(expr -> left_expression -> Type(), before_right, set, after_left, after_right);
  623. }
  624.  
  625.  
  626. DefiniteAssignmentSet *Semantic::DefiniteDefaultBinaryExpression(AstBinaryExpression *expr, BitSet &set)
  627. {
  628.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  629.     if (after_left) // if this is true there was a mistake !!!
  630.     {
  631.         set = after_left -> true_set * after_left -> false_set;
  632.         delete after_left;
  633.     }
  634.  
  635.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  636.     if (after_right) // if this is true there was a mistake !!!
  637.     {
  638.         set = (after_right -> true_set * after_right -> false_set);
  639.         delete after_right;
  640.     }
  641.  
  642.     return (DefiniteAssignmentSet *) NULL;
  643. }
  644.  
  645.  
  646. DefiniteAssignmentSet *Semantic::DefiniteBinaryExpression(AstExpression *expression, BitSet &set)
  647. {
  648.     AstBinaryExpression *binary_expression = (AstBinaryExpression *) expression;
  649.     return (this ->* DefiniteBinaryExpr[binary_expression -> binary_tag])(binary_expression, set);
  650. }
  651.  
  652.  
  653. DefiniteAssignmentSet *Semantic::DefiniteConditionalExpression(AstExpression *expression, BitSet &set)
  654. {
  655.     AstConditionalExpression *conditional_expression = (AstConditionalExpression *) expression;
  656.  
  657.     DefiniteAssignmentSet *after_condition = DefiniteExpression(conditional_expression -> test_expression, set);
  658.     BitSet *before_expressions = NULL;
  659.  
  660.     if (after_condition)
  661.          set = after_condition -> true_set;
  662.     else before_expressions = new BitSet(set);
  663.     DefiniteAssignmentSet *after_true = DefiniteExpression(conditional_expression -> true_expression, set);
  664.     BitSet *after_true_set = (BitSet *) (after_true ? NULL : new BitSet(set));
  665.  
  666.     if (after_condition)
  667.          set = after_condition -> false_set;
  668.     else set = *before_expressions;
  669.     DefiniteAssignmentSet *after_false = DefiniteExpression(conditional_expression -> false_expression, set);
  670.  
  671.     DefiniteAssignmentSet *definite = NULL;
  672.  
  673.     if (conditional_expression -> Type() == control.boolean_type)
  674.     {
  675.         definite = new DefiniteAssignmentSet(universe -> Size());
  676.  
  677.         //
  678.         //
  679.         //
  680.         if (after_true)
  681.         {
  682.             //
  683.             // before "true" expr or after it when true
  684.             //
  685.             definite -> true_set = after_true -> true_set + (after_condition ? after_condition -> true_set : *before_expressions);
  686.         }
  687.         else definite -> true_set = *after_true_set;
  688.  
  689.         if (after_false)
  690.         {
  691.             //
  692.             // before "false" expr or after it when true
  693.             //
  694.             definite -> true_set *= (after_false -> true_set +
  695.                                     (after_condition ? after_condition -> false_set : *before_expressions));
  696.         }
  697.         else definite -> true_set *= set;
  698.  
  699.         //
  700.         //
  701.         //
  702.         if (after_true)
  703.         {
  704.             //
  705.             // before "true" expr or after it when false
  706.             //
  707.             definite -> false_set = after_true -> false_set + (after_condition ? after_condition -> true_set : *before_expressions);
  708.         }
  709.         else definite -> false_set = *after_true_set;
  710.  
  711.         if (after_false)
  712.         {
  713.             //
  714.             // before "false" expr or after it when true
  715.             //
  716.             definite -> true_set *= (after_false -> false_set +
  717.                                      (after_condition ? after_condition -> false_set : *before_expressions));
  718.         }
  719.         else definite -> false_set *= set;
  720.     }
  721.     else
  722.     {
  723.         if (after_false)
  724.             set = after_false -> true_set * after_false -> false_set; // definitely assigned after the false expression ...
  725.  
  726.         // ... and definitely assigned after the true expression
  727.         if (after_true)
  728.              set *= (after_true -> true_set * after_true -> false_set);
  729.         else set *= *after_true_set;
  730.     }
  731.  
  732.     delete after_condition;    // nothing happens if after_condition is NULL
  733.     delete before_expressions; // nothing happens if before_expressions is NULL
  734.     delete after_true;         // nothing happens if after_true is NULL
  735.     delete after_true_set;     // nothing happens if after_true_set is NULL
  736.     delete after_false;        // nothing happens if after_false is NULL
  737.  
  738.     return definite;
  739. }
  740.  
  741.  
  742. DefiniteAssignmentSet *Semantic::DefiniteAssignmentExpression(AstExpression *expression, BitSet &set)
  743. {
  744.     AstAssignmentExpression *assignment_expression = (AstAssignmentExpression *) expression;
  745.  
  746.     AstExpression *left_hand_side = assignment_expression -> left_hand_side;
  747.     AstSimpleName *simple_name = left_hand_side -> SimpleNameCast();
  748.     if (simple_name)
  749.     {
  750.         if (simple_name -> resolution_opt)
  751.         {
  752.             left_hand_side = simple_name -> resolution_opt;
  753.             simple_name = left_hand_side -> SimpleNameCast();
  754.         }
  755.     }
  756.     else
  757.     {
  758.         AstFieldAccess *field_access = left_hand_side -> FieldAccessCast();
  759.         if (field_access && field_access -> resolution_opt)
  760.             left_hand_side = field_access -> resolution_opt;
  761.     }
  762.  
  763.     VariableSymbol *variable = (left_hand_side -> symbol ? left_hand_side -> symbol -> VariableCast() : (VariableSymbol *) NULL);
  764.  
  765.     //
  766.     // An array access is never considered to be final. Since no variable
  767.     // is associated with the array access, the testing for the presence of variable
  768.     // takes care of that possibility.
  769.     //
  770.     if (variable && variable -> ACC_FINAL())
  771.     {
  772.         if (variable -> IsLocal(ThisMethod()) || variable -> IsFinal(ThisType()))
  773.         {
  774.             //
  775.             // variable already initialized ?
  776.             //
  777.             if ((assignment_expression -> assignment_tag != AstAssignmentExpression::EQUAL) ||
  778.                 ((*possibly_assigned_finals) [variable -> LocalVariableIndex()]))
  779.             {
  780.                 ReportSemError(SemanticError::TARGET_VARIABLE_IS_FINAL,
  781.                                left_hand_side -> LeftToken(),
  782.                                left_hand_side -> RightToken(),
  783.                                variable -> Name());
  784.             }
  785.             else if (definite_final_assignment_stack -> Size() > 0) // are we processing the body of a loop ?
  786.                  definite_final_assignment_stack -> Top().Next() = left_hand_side;
  787.         }
  788.         else
  789.         {
  790.             ReportSemError(SemanticError::TARGET_VARIABLE_IS_FINAL,
  791.                            left_hand_side -> LeftToken(),
  792.                            left_hand_side -> RightToken(),
  793.                            variable -> Name());
  794.         }
  795.     }
  796.  
  797.     DefiniteAssignmentSet *after_left = NULL;
  798.     BitSet *before_right = NULL;
  799.     //
  800.     // The left-hand-side of an assignment expression is either a simple name,
  801.     // a field access or an array access.
  802.     //
  803.     if (! simple_name) 
  804.     {
  805.         AstFieldAccess *field_access = left_hand_side -> FieldAccessCast();
  806.         after_left = DefiniteExpression((field_access ? field_access -> base : left_hand_side), set);
  807.     }
  808.  
  809.     if (after_left)
  810.          set = after_left -> true_set * after_left -> false_set;
  811.     else before_right = new BitSet(set);
  812.  
  813.     DefiniteAssignmentSet *after_right = DefiniteExpression(assignment_expression -> expression, set);
  814.  
  815.     if (left_hand_side -> Type() == control.boolean_type)
  816.     {
  817.         DefiniteAssignmentSet *definite = NULL;
  818.     
  819.         if (assignment_expression -> assignment_tag == AstAssignmentExpression::AND_EQUAL)
  820.              definite = DefiniteAssignmentAND(control.boolean_type, before_right, set, after_left, after_right);
  821.         else if (assignment_expression -> assignment_tag == AstAssignmentExpression::XOR_EQUAL)
  822.              definite = DefiniteAssignmentXOR(control.boolean_type, before_right, set, after_left, after_right);
  823.         else if (assignment_expression -> assignment_tag == AstAssignmentExpression::IOR_EQUAL)
  824.              definite = DefiniteAssignmentIOR(control.boolean_type, before_right, set, after_left, after_right);
  825.         else
  826.         {
  827.             delete after_left;
  828.             delete before_right;
  829.             definite = after_right;
  830.         }
  831.  
  832.         if (variable && (variable -> IsLocal(ThisMethod()) || variable -> IsFinal(ThisType())))
  833.         {
  834.             if (definite)
  835.             {
  836.                 definite -> true_set.AddElement(variable -> LocalVariableIndex());
  837.                 definite -> false_set.AddElement(variable -> LocalVariableIndex());
  838.             }
  839.             else set.AddElement(variable -> LocalVariableIndex());
  840.  
  841.             if (variable -> ACC_FINAL())
  842.                 possibly_assigned_finals -> AddElement(variable -> LocalVariableIndex());
  843.         }
  844.  
  845.         return definite;
  846.     }
  847.  
  848.     if (after_right)
  849.         set = after_right -> true_set * after_right -> false_set;
  850.  
  851.     if (variable && (variable -> IsLocal(ThisMethod()) || variable -> IsFinal(ThisType())))
  852.     {
  853.         set.AddElement(variable -> LocalVariableIndex());
  854.         if (variable -> ACC_FINAL())
  855.             possibly_assigned_finals -> AddElement(variable -> LocalVariableIndex());
  856.     }
  857.  
  858.     delete after_left;   // nothing happens if after_left is NULL
  859.     delete before_right; // nothing happens if before_right is NULL
  860.     delete after_right;  // nothing happens if after_right is NULL
  861.  
  862.     return (DefiniteAssignmentSet *) NULL;
  863. }
  864.  
  865. DefiniteAssignmentSet *Semantic::DefiniteDefaultExpression(AstExpression *expr, BitSet &set)
  866. {
  867.     return (DefiniteAssignmentSet *) NULL;
  868. }
  869.  
  870. DefiniteAssignmentSet *Semantic::DefiniteParenthesizedExpression(AstExpression *expression, BitSet &set)
  871. {
  872.     AstParenthesizedExpression *expr = (AstParenthesizedExpression *) expression;
  873.  
  874.     return DefiniteExpression(expr -> expression, set);
  875. }
  876.  
  877. DefiniteAssignmentSet *Semantic::DefiniteFieldAccess(AstExpression *expression, BitSet &set)
  878. {
  879.     AstFieldAccess *expr = (AstFieldAccess *) expression;
  880.  
  881.     VariableSymbol *variable = DefiniteFinal(expr);
  882.     if (variable)
  883.     {
  884.         if (! set[variable -> LocalVariableIndex()])
  885.         {
  886.             ReportSemError(SemanticError::VARIABLE_NOT_DEFINITELY_ASSIGNED,
  887.                            expr -> LeftToken(),
  888.                            expr -> RightToken(),
  889.                            variable -> Name());
  890.             set.AddElement(variable -> LocalVariableIndex());
  891.         }
  892.     }
  893.  
  894.     return DefiniteExpression((expr -> resolution_opt ? expr -> resolution_opt : expr -> base), set);
  895. }
  896.  
  897. DefiniteAssignmentSet *Semantic::DefiniteCastExpression(AstExpression *expression, BitSet &set)
  898. {
  899.     AstCastExpression *expr = (AstCastExpression *) expression;
  900.  
  901.     return DefiniteExpression(expr -> expression, set);
  902. }
  903.  
  904. void Semantic::DefiniteArrayInitializer(AstArrayInitializer *array_initializer)
  905. {
  906.     for (int i = 0; i < array_initializer -> NumVariableInitializers(); i++)
  907.     {
  908.         AstArrayInitializer *sub_array_initializer = array_initializer -> VariableInitializer(i) -> ArrayInitializerCast();
  909.  
  910.         if (sub_array_initializer)
  911.             DefiniteArrayInitializer(sub_array_initializer);
  912.         else
  913.         {
  914.             AstExpression *init = (AstExpression *) array_initializer -> VariableInitializer(i);
  915.             DefiniteAssignmentSet *after_init = DefiniteExpression(init, *definitely_assigned_variables);
  916.             if (after_init)
  917.             {
  918.                 *definitely_assigned_variables = after_init -> true_set * after_init -> false_set;
  919.                 delete after_init;
  920.             }
  921.         }
  922.     }
  923.  
  924.     return;
  925. }
  926.  
  927.  
  928. inline void Semantic::DefiniteVariableInitializer(AstVariableDeclarator *variable_declarator)
  929. {
  930.     AstArrayInitializer *array_initializer = variable_declarator -> variable_initializer_opt -> ArrayInitializerCast();
  931.     if (array_initializer)
  932.         DefiniteArrayInitializer(array_initializer);
  933.     else
  934.     {
  935.         AstExpression *init = (AstExpression *) variable_declarator -> variable_initializer_opt;
  936.         DefiniteAssignmentSet *after_init = DefiniteExpression(init, *definitely_assigned_variables);
  937.         if (after_init)
  938.         {
  939.             *definitely_assigned_variables = after_init -> true_set * after_init -> false_set;
  940.             delete after_init;
  941.         }
  942.     }
  943.  
  944.     return;
  945. }
  946.  
  947.  
  948. inline void Semantic::DefiniteBlockStatements(AstBlock *block_body)
  949. {
  950.     for (int i = 0; i < block_body -> NumStatements(); i++)
  951.     {
  952.         AstStatement *statement = (AstStatement *) block_body -> Statement(i);
  953.         if (statement -> is_reachable)
  954.              DefiniteStatement(statement);
  955.         else break;
  956.     }
  957.  
  958.     return;
  959. }
  960.  
  961.  
  962. void Semantic::DefiniteBlock(Ast *stmt)
  963. {
  964.     AstBlock *block_body = (AstBlock *) stmt;
  965.  
  966.     definite_block_stack -> Push(block_body);
  967.  
  968.     for (int i = 0; i < block_body -> block_symbol -> NumVariableSymbols(); i++)
  969.     {
  970.         VariableSymbol *variable = block_body -> block_symbol -> VariableSym(i);
  971.  
  972.         definitely_assigned_variables -> RemoveElement(variable -> LocalVariableIndex());
  973.         definite_visible_variables -> AddElement(variable);
  974.     }
  975.  
  976.     DefiniteBlockStatements(block_body);
  977.  
  978.     for (int k = 0; k < block_body -> block_symbol -> NumVariableSymbols(); k++)
  979.         definite_visible_variables -> RemoveElement(block_body -> block_symbol -> VariableSym(k));
  980.  
  981.     //
  982.     // Note that in constructing the Ast, the parser encloses each
  983.     // labeled statement in its own block... Therefore, only blocks
  984.     // are labeled.
  985.     //
  986.     if (block_body -> label_token_opt)
  987.         *definitely_assigned_variables *= definite_block_stack -> TopBreakSet();
  988.  
  989.     definite_block_stack -> Pop();
  990.  
  991.     return;
  992. }
  993.  
  994.  
  995. void Semantic::DefiniteLocalVariableDeclarationStatement(Ast *stmt)
  996. {
  997.     AstLocalVariableDeclarationStatement *local_decl = (AstLocalVariableDeclarationStatement *) stmt;
  998.  
  999.     for (int i = 0; i < local_decl -> NumVariableDeclarators(); i++)
  1000.     {
  1001.         AstVariableDeclarator *variable_declarator = local_decl -> VariableDeclarator(i);
  1002.         VariableSymbol *variable_symbol = variable_declarator -> symbol;
  1003.         if (variable_symbol)
  1004.         {
  1005.             if (variable_declarator -> variable_initializer_opt)
  1006.             {
  1007.                 DefiniteVariableInitializer(variable_declarator);
  1008.                 definitely_assigned_variables -> AddElement(variable_symbol -> LocalVariableIndex());
  1009.                 if (variable_symbol -> ACC_FINAL())
  1010.                     possibly_assigned_finals -> AddElement(variable_symbol -> LocalVariableIndex());
  1011.             }
  1012.             else definitely_assigned_variables -> RemoveElement(variable_symbol -> LocalVariableIndex());
  1013.         }
  1014.     }
  1015.  
  1016.     return;
  1017. }
  1018.  
  1019.  
  1020. void Semantic::DefiniteExpressionStatement(Ast *stmt)
  1021. {
  1022.     AstExpressionStatement *expression_statement = (AstExpressionStatement *) stmt;
  1023.  
  1024.     DefiniteAssignmentSet *after_expr = DefiniteExpression(expression_statement -> expression, *definitely_assigned_variables);
  1025.     if (after_expr)
  1026.     {
  1027.         *definitely_assigned_variables = after_expr -> true_set * after_expr -> false_set;
  1028.         delete after_expr;
  1029.     }
  1030.  
  1031.    return;
  1032. }
  1033.  
  1034.  
  1035. void Semantic::DefiniteSynchronizedStatement(Ast *stmt)
  1036. {
  1037.     AstSynchronizedStatement *synchronized_statement = (AstSynchronizedStatement *) stmt;
  1038.  
  1039.     DefiniteAssignmentSet *after_expr = DefiniteExpression(synchronized_statement -> expression, *definitely_assigned_variables);
  1040.     if (after_expr)
  1041.     {
  1042.         *definitely_assigned_variables = after_expr -> true_set * after_expr -> false_set;
  1043.         delete after_expr;
  1044.     }
  1045.  
  1046.     DefiniteBlock(synchronized_statement -> block);
  1047.  
  1048.     return;
  1049. }
  1050.  
  1051.  
  1052. void Semantic::DefiniteIfStatement(Ast *stmt)
  1053. {
  1054.     AstIfStatement *if_statement = (AstIfStatement *) stmt;
  1055.  
  1056.     DefiniteAssignmentSet *after_expr = DefiniteExpression(if_statement -> expression, *definitely_assigned_variables);
  1057.     BitSet after_expr_finals(*possibly_assigned_finals);
  1058.     BitSet *starting_set = (after_expr ? (BitSet *) NULL : new BitSet(*definitely_assigned_variables));
  1059.     if (after_expr)
  1060.          *definitely_assigned_variables = after_expr -> true_set;
  1061.  
  1062.     //
  1063.     // If the expression in the if-statement is a boolean constant expression then get its value.
  1064.     //
  1065.     IntLiteralValue *if_constant_expr = (if_statement -> expression -> Type() == control.boolean_type &&
  1066.                                          if_statement -> expression -> IsConstant()
  1067.                                                                      ? (IntLiteralValue *) if_statement -> expression -> value
  1068.                                                                      : (IntLiteralValue *) NULL);
  1069.     //
  1070.     // If either the expression is not constant or its value is true, then 
  1071.     // check the statement that make up the true part of the if statement
  1072.     //
  1073.     if ((! if_constant_expr) || if_constant_expr -> value)
  1074.         DefiniteBlock(if_statement -> true_statement);
  1075.  
  1076.     //
  1077.     // Recall that the parser ensures that the statements that appear in an if-statement
  1078.     // (both the true and false statement) are enclosed in a block.
  1079.     //
  1080.     if (! if_statement -> false_statement_opt) // no else part ?
  1081.     {
  1082.         *definitely_assigned_variables *= (after_expr ? after_expr -> false_set : *starting_set);
  1083.         *possibly_assigned_finals += after_expr_finals;
  1084.     }
  1085.     else
  1086.     {
  1087.         BitSet after_true_finals(*possibly_assigned_finals);
  1088.         *possibly_assigned_finals = after_expr_finals;
  1089.  
  1090.         BitSet true_set(*definitely_assigned_variables);
  1091.         *definitely_assigned_variables = (after_expr ? after_expr -> false_set : *starting_set);
  1092.  
  1093.         if ((! if_constant_expr) || (! if_constant_expr -> value)) // either the expression is not constant or its value is false?
  1094.             DefiniteBlock(if_statement -> false_statement_opt);
  1095.  
  1096.         *definitely_assigned_variables *= true_set;
  1097.         *possibly_assigned_finals += after_true_finals;
  1098.     }
  1099.  
  1100.     delete after_expr;   // nothing happens if after_expr is NULL
  1101.     delete starting_set; // nothing happens if starting_set is NULL
  1102.  
  1103.     return;
  1104. }
  1105.  
  1106.  
  1107. void Semantic::DefiniteLoopBody(AstStatement *statement)
  1108. {
  1109.     definite_final_assignment_stack -> Push();
  1110.  
  1111.     BitSet starting_set(*possibly_assigned_finals);
  1112.  
  1113.     DefiniteStatement(statement);
  1114.  
  1115.     BitSet exit_set(*possibly_assigned_finals);
  1116.     exit_set += definite_block_stack -> TopFinalContinueSet();
  1117.  
  1118.     //
  1119.     // The set of variables that may have been possibly assigned within the body of a loop
  1120.     // consists of the set of variables that was possibly assigned at the end of the block
  1121.     // UNION the set of variables that was possibly assigned prior to a continue statement
  1122.     // within the body of the loop MINUS the set of variables that were possibly assigned
  1123.     // prior to entering the loop.
  1124.     //
  1125.     BitSet new_set(exit_set);
  1126.     new_set -= starting_set;
  1127.  
  1128.     for (int k = 0; k < definite_final_assignment_stack -> Top().Length(); k++)
  1129.     {
  1130.         AstExpression *name = definite_final_assignment_stack -> Top()[k];
  1131.         VariableSymbol *variable = (VariableSymbol *) name -> symbol;
  1132.  
  1133.         if (definite_visible_variables -> IsElement(variable) && new_set[variable -> LocalVariableIndex()])
  1134.         {
  1135.             ReportSemError(SemanticError::FINAL_VARIABLE_TARGET_IN_LOOP,
  1136.                            name -> LeftToken(),
  1137.                            name -> RightToken(),
  1138.                            variable -> Name());
  1139.         }
  1140.     }
  1141.  
  1142.     exit_set += definite_block_stack -> TopFinalBreakSet();
  1143.     *possibly_assigned_finals = exit_set;
  1144.     definite_final_assignment_stack -> Pop();
  1145.  
  1146.     return;
  1147. }
  1148.  
  1149.  
  1150. void Semantic::DefiniteWhileStatement(Ast *stmt)
  1151. {
  1152.     AstWhileStatement *while_statement = (AstWhileStatement *) stmt;
  1153.  
  1154.     BreakableStatementStack().Push(definite_block_stack -> TopBlock());
  1155.     ContinuableStatementStack().Push(stmt);
  1156.  
  1157.     DefiniteAssignmentSet *after_expr = DefiniteExpression(while_statement -> expression, *definitely_assigned_variables);
  1158.  
  1159.     bool while_expr = true;
  1160.     if (while_statement -> expression -> Type() == control.boolean_type && while_statement -> expression -> IsConstant())
  1161.     {
  1162.         IntLiteralValue *literal = (IntLiteralValue *) while_statement -> expression -> value;
  1163.         if (! literal -> value)
  1164.             while_expr = false;
  1165.     }
  1166.  
  1167.     if (after_expr)
  1168.     {
  1169.         *definitely_assigned_variables = after_expr -> true_set;
  1170.         //
  1171.         // If the expression is always false, the body of the loop is not reachable and therefore will never execute.
  1172.         //
  1173.         if (while_expr)
  1174.             DefiniteLoopBody(while_statement -> statement);
  1175.         *definitely_assigned_variables = (after_expr -> false_set * definite_block_stack -> TopBreakSet());
  1176.         delete after_expr;
  1177.     }
  1178.     else
  1179.     {
  1180.         BitSet starting_set(*definitely_assigned_variables);
  1181.         //
  1182.         // If the expression is always false, the body of the loop is not reachable and therefore will never execute.
  1183.         //
  1184.         if (while_expr)
  1185.             DefiniteLoopBody(while_statement -> statement);
  1186.         *definitely_assigned_variables = (starting_set * definite_block_stack -> TopBreakSet());
  1187.     }
  1188.  
  1189.     ContinuableStatementStack().Pop();
  1190.     BreakableStatementStack().Pop();
  1191.  
  1192.     return;
  1193. }
  1194.  
  1195.  
  1196. void Semantic::DefiniteForStatement(Ast *stmt)
  1197. {
  1198.     AstForStatement *for_statement = (AstForStatement *) stmt;
  1199.  
  1200.     //
  1201.     // Note that in constructing the Ast, the parser encloses each
  1202.     // for-statement whose for-init-statements starts with a local
  1203.     // variable declaration in its own block. Therefore a redeclaration
  1204.     // of another local variable with the same name in a different loop
  1205.     // at the same nesting level will not cause any conflict.
  1206.     //
  1207.     // For example, the following sequence of statements is legal:
  1208.     //
  1209.     //     for (int i = 0; i < 10; i++);
  1210.     //     for (int i = 10; i < 20; i++);
  1211.     //
  1212.     for (int i = 0; i < for_statement -> NumForInitStatements(); i++)
  1213.         DefiniteStatement(for_statement -> ForInitStatement(i));
  1214.  
  1215.     BreakableStatementStack().Push(definite_block_stack -> TopBlock());
  1216.     ContinuableStatementStack().Push(stmt);
  1217.  
  1218.     DefiniteAssignmentSet *after_end_expression = NULL;
  1219.     BitSet before_statement(universe -> Size());
  1220.  
  1221.     bool for_expr = true;
  1222.     if (for_statement -> end_expression_opt)
  1223.     {
  1224.         after_end_expression = DefiniteExpression(for_statement -> end_expression_opt, *definitely_assigned_variables);
  1225.  
  1226.         if (for_statement -> end_expression_opt -> Type() == control.boolean_type &&
  1227.             for_statement -> end_expression_opt -> IsConstant())
  1228.         {
  1229.             IntLiteralValue *literal = (IntLiteralValue *) for_statement -> end_expression_opt -> value;
  1230.             if (! literal -> value)
  1231.                 for_expr = false;
  1232.         }
  1233.     }
  1234.  
  1235.     if (after_end_expression)
  1236.          *definitely_assigned_variables = after_end_expression -> true_set;
  1237.     else before_statement = *definitely_assigned_variables;
  1238.  
  1239.     //
  1240.     // If the expression is always false, the body of the loop is not reachable and therefore will never execute.
  1241.     //
  1242.     if (for_expr)
  1243.         DefiniteLoopBody(for_statement -> statement);
  1244.  
  1245.     //
  1246.     // Compute the set of variables that are definitely assigned after the
  1247.     // contained statement and after every continue statement that may exit
  1248.     // the body of the for statement.
  1249.     //
  1250.     *definitely_assigned_variables *= definite_block_stack -> TopContinueSet();
  1251.     for (int j = 0; j < for_statement -> NumForUpdateStatements(); j++)
  1252.         DefiniteExpressionStatement(for_statement -> ForUpdateStatement(j));
  1253.  
  1254.     //
  1255.     // Compute the set of variables that belongs to both sets below:
  1256.     // 
  1257.     //    . the universe if no condition expression is present;
  1258.     //      otherwise, the set of variables that is definitely assigned when
  1259.     //      the condition expression is false.
  1260.     //
  1261.     //    . the set of variables that is definitely assigned before every
  1262.     //      break statement that may exit the for statement.
  1263.     //
  1264.     *definitely_assigned_variables = (for_statement -> end_expression_opt
  1265.                                                      ? (after_end_expression ? after_end_expression -> false_set : before_statement)
  1266.                                                      : *universe); // set of variables that depend on the condition
  1267.  
  1268.     //
  1269.     // The replacement
  1270.     //
  1271.     *definitely_assigned_variables *= definite_block_stack -> TopBreakSet();
  1272.  
  1273.     delete after_end_expression; // nothing happens if after_end_expression is NULL
  1274.  
  1275.     ContinuableStatementStack().Pop();
  1276.     BreakableStatementStack().Pop();
  1277.  
  1278.     return;
  1279. }
  1280.  
  1281.  
  1282. void Semantic::DefiniteDoStatement(Ast *stmt)
  1283. {
  1284.     AstDoStatement *do_statement = (AstDoStatement *) stmt;
  1285.  
  1286.     BreakableStatementStack().Push(definite_block_stack -> TopBlock());
  1287.     ContinuableStatementStack().Push(stmt);
  1288.  
  1289.     bool do_expr = true;
  1290.     if (do_statement -> expression -> Type() == control.boolean_type && do_statement -> expression -> IsConstant())
  1291.     {
  1292.         IntLiteralValue *literal = (IntLiteralValue *) do_statement -> expression -> value;
  1293.         if (! literal -> value)
  1294.             do_expr = false;
  1295.     }
  1296.  
  1297.     if (do_expr)
  1298.          DefiniteLoopBody(do_statement -> statement);
  1299.     else DefiniteStatement(do_statement -> statement); // The expression is always false therefore, loop will execute exactly once.
  1300.  
  1301.     BitSet after_stmt(*definitely_assigned_variables);
  1302.     *definitely_assigned_variables *= definite_block_stack -> TopContinueSet();
  1303.     DefiniteAssignmentSet *after_expr = DefiniteExpression(do_statement -> expression, *definitely_assigned_variables);
  1304.     if (after_expr)
  1305.     {
  1306.         *definitely_assigned_variables = (after_expr -> false_set * definite_block_stack -> TopBreakSet());
  1307.         delete after_expr;
  1308.     }
  1309.     else *definitely_assigned_variables *= definite_block_stack -> TopBreakSet();
  1310.  
  1311.     ContinuableStatementStack().Pop();
  1312.     BreakableStatementStack().Pop();
  1313.  
  1314.     return;
  1315. }
  1316.  
  1317.  
  1318. void Semantic::DefiniteSwitchStatement(Ast *stmt)
  1319. {
  1320.     AstSwitchStatement *switch_statement = (AstSwitchStatement *) stmt;
  1321.  
  1322.     AstBlock *block_body = switch_statement -> switch_block;
  1323.     definite_block_stack -> Push(block_body);
  1324.     BreakableStatementStack().Push(block_body);
  1325.  
  1326.     DefiniteAssignmentSet *after_expr = DefiniteExpression(switch_statement -> expression, *definitely_assigned_variables);
  1327.     if (after_expr)
  1328.     {
  1329.         *definitely_assigned_variables = after_expr -> true_set * after_expr -> false_set;
  1330.         delete after_expr;
  1331.     }
  1332.  
  1333.     BitSet starting_set(*definitely_assigned_variables),
  1334.            after_expr_finals(*possibly_assigned_finals),
  1335.            switch_finals_union(*possibly_assigned_finals);
  1336.  
  1337.     for (int i = 0; i < block_body -> NumStatements(); i++)
  1338.     {
  1339.         AstSwitchBlockStatement *switch_block_statement = (AstSwitchBlockStatement *) block_body -> Statement(i);
  1340.  
  1341.         if (switch_block_statement -> NumStatements() > 0)
  1342.         {
  1343.             *definitely_assigned_variables = starting_set;
  1344.             *possibly_assigned_finals = after_expr_finals;
  1345.  
  1346.             for (int k = 0; k < switch_block_statement -> NumStatements(); k++)
  1347.             {
  1348.                 AstStatement *statement = (AstStatement *) switch_block_statement -> Statement(k);
  1349.                 if (statement -> is_reachable)
  1350.                      DefiniteStatement(statement);
  1351.                 else break;
  1352.             }
  1353.  
  1354.             //
  1355.             // Update possibly_assigned_finals here. If a continue, break (of an enclosing statement), return or throw
  1356.             // statement was encountered...
  1357.             //
  1358.             switch_finals_union += definite_block_stack -> TopFinalExitSet(*possibly_assigned_finals);
  1359.         }
  1360.     }
  1361.  
  1362.     if (switch_statement -> default_case.switch_block_statement) // Is there a default case?
  1363.          *definitely_assigned_variables *= definite_block_stack -> TopBreakSet();
  1364.     else *definitely_assigned_variables = starting_set;
  1365.  
  1366.     *possibly_assigned_finals = switch_finals_union;
  1367.  
  1368.     BreakableStatementStack().Pop();
  1369.     definite_block_stack -> Pop();
  1370.  
  1371.     return;
  1372. }
  1373.  
  1374.  
  1375. void Semantic::DefiniteBreakStatement(Ast *stmt)
  1376. {
  1377.     AstBreakStatement *break_statement = (AstBreakStatement *) stmt;
  1378.  
  1379.     //
  1380.     // Compute the set of variables that are definitely assigned prior to executing the break.
  1381.     //
  1382.     definite_block_stack -> BreakSet(break_statement -> nesting_level) *= (*definitely_assigned_variables);
  1383.     definite_block_stack -> FinalBreakSet(break_statement -> nesting_level) += (*possibly_assigned_finals);
  1384.  
  1385.     //
  1386.     // After execution of a break statement, it is vacuously true 
  1387.     // that every variable has definitely been assigned and no final
  1388.     // variable has been possibly assigned (as nothing is reachable
  1389.     // any way).
  1390.     //
  1391.     *definitely_assigned_variables = *universe;
  1392.     possibly_assigned_finals -> SetEmpty();
  1393.  
  1394.     return;
  1395. }
  1396.  
  1397.  
  1398. void Semantic::DefiniteContinueStatement(Ast *stmt)
  1399. {
  1400.     AstContinueStatement *continue_statement = (AstContinueStatement *) stmt;
  1401.  
  1402.     //
  1403.     // Compute the set of variables that are definitely assigned prior to executing the continue.
  1404.     //
  1405.     definite_block_stack -> ContinueSet(continue_statement -> nesting_level) *= (*definitely_assigned_variables);
  1406.     definite_block_stack -> FinalContinueSet(continue_statement -> nesting_level) += (*possibly_assigned_finals);
  1407.  
  1408.     //
  1409.     // After execution of a continue statement, it is vacuously true 
  1410.     // that every variable has definitely been assigned and no final
  1411.     // variable has been possibly assigned (as nothing is reachable
  1412.     // any way).
  1413.     //
  1414.     *definitely_assigned_variables = *universe;
  1415.     possibly_assigned_finals -> SetEmpty();
  1416.  
  1417.     return;
  1418. }
  1419.  
  1420.  
  1421. void Semantic::DefiniteReturnStatement(Ast *stmt)
  1422. {
  1423.     AstReturnStatement *return_statement = (AstReturnStatement *) stmt;
  1424.  
  1425.     if (return_statement -> expression_opt)
  1426.     {
  1427.         DefiniteAssignmentSet *after_expr = DefiniteExpression(return_statement -> expression_opt, *definitely_assigned_variables);
  1428.         if (after_expr)
  1429.             delete after_expr;
  1430.     }
  1431.  
  1432.     //
  1433.     // Compute the set of variables that are definitely assigned prior to executing
  1434.     // this return statement. Note that this set is only relevant to the method or
  1435.     // constructor block containing this statement.
  1436.     //
  1437.     definite_block_stack -> TopReturnSet() *= (*definitely_assigned_variables);
  1438.  
  1439.     //
  1440.     // Compute the set of variables that are possibly assigned prior to executing this return statement.
  1441.     // We have a few cases to consider:
  1442.     //
  1443.     //    1. The return statement is not contained in a try statement - the possibly-assigned set is only relevant
  1444.     //       to the enclosing method (or constructor) block. The definitely assigned set is updated as if the return
  1445.     //       statement was a break statement out of the method (or constructor) block.
  1446.     //
  1447.     //    2. If the return statement is contained in a try main block or a try
  1448.     //       catch block that contains a finally clause - the possibly-assigned
  1449.     //       block is relevant to that main try block or catch block.
  1450.     //
  1451.     //    3. otherwise, treat the return statement as if it immediately followed its containing try statement
  1452.     //
  1453.     if (definite_try_stack -> Size() == 0)
  1454.         definite_block_stack -> ReturnSet(0) *= (*definitely_assigned_variables);
  1455.     else
  1456.     {
  1457.         for (int i = definite_try_stack -> Size() - 1; i >= 0; i--)
  1458.         {
  1459.             AstTryStatement *try_statement = definite_try_stack -> TryStatement(i);
  1460.             //
  1461.             // Is the return statement enclosed in a try main block or catch block
  1462.             // that  contains a finally clause. Note that a try statement is removed from
  1463.             // the definite_try_stack before its finally clause is processed. thus, a return
  1464.             // statement that is enclosed in a finally clause will appear in an enclosing
  1465.             // try statement, if any...
  1466.             //
  1467.             if (try_statement -> finally_clause_opt)
  1468.             {
  1469.                 int k;
  1470.                 for (k = definite_block_stack -> Size() - 1;
  1471.                      definite_block_stack -> Block(k) != definite_try_stack -> Block(i);
  1472.                      k--)
  1473.                     ;
  1474. assert(k >= 0);
  1475.                 definite_block_stack -> FinalReturnSet(k) += (*possibly_assigned_finals);
  1476.                 break;
  1477.             }
  1478.         }
  1479.     }
  1480.  
  1481.     //
  1482.     // After execution of a return statement, it is vacuously true 
  1483.     // that every variable has definitely been assigned and no final
  1484.     // variable has been possibly assigned (as nothing is reachable
  1485.     // any way).
  1486.     //
  1487.     *definitely_assigned_variables = *universe;
  1488.     possibly_assigned_finals -> SetEmpty();
  1489.  
  1490.     return;
  1491. }
  1492.  
  1493.  
  1494. void Semantic::DefiniteThrowStatement(Ast *stmt)
  1495. {
  1496.     AstThrowStatement *throw_statement = (AstThrowStatement *) stmt;
  1497.  
  1498.     DefiniteAssignmentSet *after_expr = DefiniteExpression(throw_statement -> expression, *definitely_assigned_variables);
  1499.     if (after_expr)
  1500.         delete after_expr;
  1501.  
  1502.     //
  1503.     // Compute the set of variables that are definitely assigned prior to executing
  1504.     // this throw statement. Note that this set is only relevant to the method or
  1505.     // constructor block containing this statement.
  1506.     //
  1507.     definite_block_stack -> TopThrowSet() *= (*definitely_assigned_variables);
  1508.  
  1509.     //
  1510.     // Compute the set of variables that are possibly assigned prior to executing this throw statement
  1511.     // and update the proper enclosing block appropriately.
  1512.     //
  1513.     // We have a few cases to consider:
  1514.     //
  1515.     //    1. The throw statement is not contained in a try statement - the possibly-assigned 
  1516.     //       set is only relevant to the enclosing method (or constructor) block. If the
  1517.     //       containing function in question is a method (i.e., not a constructor) then the
  1518.     //       definitely assigned set is updated as if the throw statement was a break statement
  1519.     //       out of the method block.
  1520.     //
  1521.     //    2. The throw statement is enclosed in a try statement main block or catch clause.
  1522.     //
  1523.     //        2a. if the nearest try-block that encloses the throw statement is a main try-block -
  1524.     //            the possibly-assigned block is relevant to that main block.
  1525.     //
  1526.     //        2b. if the nearest try-block that encloses the throw statement is a catch-block and
  1527.     //            the try block contains a finally clause - the possibly-assigned block is relevant
  1528.     //            to the catch-block
  1529.     //
  1530.     //        2c. otherwise, treat the throw statement as if it immediately followed its containing
  1531.     //            try statement
  1532.     //
  1533.     if (definite_try_stack -> Size() == 0)
  1534.     {
  1535.         if (ThisMethod() -> Identity() != control.init_name_symbol) // Not a constructor
  1536.             definite_block_stack -> ThrowSet(0) *= (*definitely_assigned_variables);
  1537.     }
  1538.     else
  1539.     {
  1540.         for (int i = definite_try_stack -> Size() - 1; i >= 0; i--)
  1541.         {
  1542.             AstTryStatement *try_statement = definite_try_stack -> TryStatement(i);
  1543.             //
  1544.             // Is the return statement enclosed in a try main block or catch block
  1545.             // that  contains a finally clause. Note that a try statement is removed from
  1546.             // the definite_try_stack before its finally clause is processed. thus, a return
  1547.             // statement that is enclosed in a finally clause will appear in an enclosing
  1548.             // try statement, if any...
  1549.             //
  1550.             if (try_statement -> block == definite_try_stack -> Block(i)) // Is the throw statement enclosed in main try block?
  1551.             {
  1552.                 int k;
  1553.                 for (k = definite_block_stack -> Size() - 1; definite_block_stack -> Block(k) != try_statement -> block; k--)
  1554.                     ;
  1555. assert(k >= 0);
  1556.                 definite_block_stack -> FinalThrowSet(k) += (*possibly_assigned_finals);
  1557.                 break;
  1558.             }
  1559.             else if (try_statement -> finally_clause_opt)
  1560.             {
  1561.                 int k;
  1562.                 for (k = definite_block_stack -> Size() - 1;
  1563.                      definite_block_stack -> Block(k) != definite_try_stack -> Block(i);
  1564.                      k--)
  1565.                     ;
  1566. assert(k >= 0);
  1567.                 definite_block_stack -> FinalThrowSet(k) += (*possibly_assigned_finals);
  1568.                 break;
  1569.             }
  1570.         }
  1571.     }
  1572.  
  1573.     //
  1574.     // After execution of a throw statement, it is vacuously true 
  1575.     // that every variable has definitely been assigned and no final
  1576.     // variable has been possibly assigned (as nothing is reachable
  1577.     // any way).
  1578.     //
  1579.     *definitely_assigned_variables = *universe;
  1580.     possibly_assigned_finals -> SetEmpty();
  1581.  
  1582.     return;
  1583. }
  1584.  
  1585.  
  1586. void Semantic::DefiniteTryStatement(Ast *stmt)
  1587. {
  1588.     AstTryStatement *try_statement = (AstTryStatement *) stmt;
  1589.     definite_try_stack -> Push(try_statement);
  1590.  
  1591.     BitSet starting_set(*definitely_assigned_variables);
  1592.  
  1593.     AstBlock *try_block_body = try_statement -> block;
  1594.     definite_block_stack -> Push(try_block_body);
  1595.     definite_try_stack -> SetTopBlock(try_block_body);
  1596.  
  1597.     for (int j = 0; j < try_block_body -> block_symbol -> NumVariableSymbols(); j++)
  1598.     {
  1599.         VariableSymbol *variable = try_block_body -> block_symbol -> VariableSym(j);
  1600.  
  1601.         definitely_assigned_variables -> RemoveElement(variable -> LocalVariableIndex());
  1602.         definite_visible_variables -> AddElement(variable);
  1603.     }
  1604.  
  1605.     BitSet before_try_finals(*possibly_assigned_finals);
  1606.  
  1607.     DefiniteBlockStatements(try_block_body);
  1608.  
  1609.     BitSet &exit_set = definite_block_stack -> TopFinalExitSet(*possibly_assigned_finals),
  1610.            before_catch_finals(exit_set),
  1611.            possibly_finals_union(exit_set);
  1612.  
  1613.     //
  1614.     // Once we are done with a block, its enclosed local variables are no longer visible.
  1615.     //
  1616.     for (int l = 0; l < try_block_body -> block_symbol -> NumVariableSymbols(); l++)
  1617.         definite_visible_variables -> RemoveElement(try_block_body -> block_symbol -> VariableSym(l));
  1618.  
  1619.     definite_block_stack -> Pop();
  1620.  
  1621.     //
  1622.     // We initilize the variable after_blocks here. It is used to calculate intersection
  1623.     // of the set of variables that are definitely assigned by all the blocks: the try block,
  1624.     // all the catch blocks, if any, and the finally block, if there is one.
  1625.     //
  1626.     BitSet after_blocks(*definitely_assigned_variables);
  1627.  
  1628.     //
  1629.     // Recall that the body of the catch blocks must not be
  1630.     // processed within the environment of the associated try whose
  1631.     // exceptions they are supposed to catch but within the immediate
  1632.     // enclosing block (which may itself be a try block).
  1633.     //
  1634.     for (int i = 0; i < try_statement -> NumCatchClauses(); i++)
  1635.     {
  1636.         *definitely_assigned_variables = starting_set;
  1637.  
  1638.         //
  1639.         // We process the catch block here instead of invoking DefiniteBlock,
  1640.         // in order to make sure that the formal parameter (which is declared)
  1641.         // inside the block is identified as having been definitely assigned.
  1642.         //
  1643.         AstCatchClause *clause = try_statement -> CatchClause(i);
  1644.  
  1645.         AstBlock *clause_block_body = clause -> block;
  1646.         definite_block_stack -> Push(clause_block_body);
  1647.         definite_try_stack -> SetTopBlock(clause_block_body);
  1648.  
  1649.         for (int j = 0; j < clause_block_body -> block_symbol -> NumVariableSymbols(); j++)
  1650.         {
  1651.             VariableSymbol *variable = clause_block_body -> block_symbol -> VariableSym(j);
  1652.  
  1653.             definitely_assigned_variables -> RemoveElement(variable -> LocalVariableIndex());
  1654.             definite_visible_variables -> AddElement(variable);
  1655.         }
  1656.  
  1657.         //
  1658.         // The parameter must be (re) added after removing all variables in the block
  1659.         // from the set !!!
  1660.         //
  1661.         definitely_assigned_variables -> AddElement(clause -> parameter_symbol -> LocalVariableIndex());
  1662.         *possibly_assigned_finals = before_catch_finals;
  1663.         if (clause -> parameter_symbol -> ACC_FINAL())
  1664.             possibly_assigned_finals -> AddElement(clause -> parameter_symbol -> LocalVariableIndex());
  1665.  
  1666.         DefiniteBlockStatements(clause_block_body);
  1667.  
  1668.         //
  1669.         // Once we are done with a block, its enclosed local variables are no longer visible.
  1670.         //
  1671.         for (int k = 0; k < clause_block_body -> block_symbol -> NumVariableSymbols(); k++)
  1672.             definite_visible_variables -> RemoveElement(clause_block_body -> block_symbol -> VariableSym(k));
  1673.  
  1674.         possibly_finals_union += definite_block_stack -> TopFinalExitSet(*possibly_assigned_finals);
  1675.  
  1676.         definite_block_stack -> Pop();
  1677.  
  1678.         //
  1679.         // Process the set of variables that were definitely assigned
  1680.         // after this catch block
  1681.         //
  1682.         after_blocks *= *definitely_assigned_variables;
  1683.     }
  1684.  
  1685.     *possibly_assigned_finals = possibly_finals_union;
  1686.     definite_try_stack -> Pop();
  1687.  
  1688.     //
  1689.     // Like the catch clauses, a finally block must not be processed
  1690.     // in the environment of its associated try block but in the
  1691.     // environment of its immediate enclosing block.
  1692.     //
  1693.     if (try_statement -> finally_clause_opt)
  1694.     {
  1695.         *definitely_assigned_variables = starting_set;
  1696.  
  1697.         DefiniteBlock(try_statement -> finally_clause_opt -> block);
  1698.  
  1699.         *definitely_assigned_variables += after_blocks;
  1700.     }
  1701.     else *definitely_assigned_variables = after_blocks;
  1702.  
  1703.     return;
  1704. }
  1705.  
  1706.  
  1707. void Semantic::DefiniteEmptyStatement(Ast *stmt)
  1708. {
  1709.     return;
  1710. }
  1711.  
  1712.  
  1713. void Semantic::DefiniteClassDeclaration(Ast *decl)
  1714. {
  1715.     //
  1716.     // All the methods within the body of a local class are processed when
  1717.     // the class is compiled.
  1718.     //
  1719.  
  1720.     return;
  1721. }
  1722.  
  1723.  
  1724. void Semantic::DefiniteMethodBody(AstMethodDeclaration *method_declaration, Tuple<VariableSymbol *> &finals)
  1725. {
  1726.     if (! method_declaration -> method_body -> EmptyStatementCast())
  1727.     {
  1728.         AstConstructorBlock *constructor_block = method_declaration -> method_body -> ConstructorBlockCast();
  1729.         AstBlock *block_body = (constructor_block ? constructor_block -> block : (AstBlock *) method_declaration -> method_body);
  1730.  
  1731.         universe = new BitSet(block_body -> block_symbol -> max_variable_index + finals.Length(), BitSet::UNIVERSE);
  1732.         definite_block_stack = new DefiniteBlockStack(method_declaration -> method_symbol -> max_block_depth, universe -> Size());
  1733.         definite_try_stack = new DefiniteTryStack(method_declaration -> method_symbol -> max_block_depth);
  1734.         definite_final_assignment_stack =  new DefiniteFinalAssignmentStack();
  1735.         definite_visible_variables = new SymbolSet(universe -> Size());
  1736.         definitely_assigned_variables = new BitSet(universe -> Size(), BitSet::EMPTY);
  1737.         possibly_assigned_finals = new BitSet(universe -> Size(), BitSet::EMPTY);
  1738.         for (int i = 0; i < finals.Length(); i++) // Assume that all final instance variables have been assigned a value.
  1739.         {
  1740.             int index = block_body -> block_symbol -> max_variable_index + i;
  1741.             finals[i] -> SetLocalVariableIndex(index);
  1742.             definitely_assigned_variables -> AddElement(index);
  1743.             possibly_assigned_finals -> AddElement(index);
  1744.             definite_visible_variables -> AddElement(finals[i]);
  1745.         }
  1746.  
  1747.         definite_block_stack -> Push(block_body);
  1748.  
  1749.         AstMethodDeclarator *method_declarator = method_declaration -> method_declarator;
  1750.         for (int k = 0; k < method_declarator -> NumFormalParameters(); k++)
  1751.         {
  1752.             AstFormalParameter *parameter = method_declarator -> FormalParameter(k);
  1753.             definitely_assigned_variables -> AddElement(parameter -> parameter_symbol -> LocalVariableIndex());
  1754.             if (parameter -> parameter_symbol -> ACC_FINAL())
  1755.                 possibly_assigned_finals -> AddElement(parameter -> parameter_symbol -> LocalVariableIndex());
  1756.             definite_visible_variables -> AddElement(parameter -> parameter_symbol);
  1757.         }
  1758.  
  1759.         for (int l = 0; l < block_body -> block_symbol -> NumVariableSymbols(); l++)
  1760.             definite_visible_variables -> AddElement(block_body -> block_symbol -> VariableSym(l));
  1761.  
  1762.         DefiniteBlockStatements(block_body);
  1763.  
  1764.         definite_block_stack -> Pop();
  1765.  
  1766.         delete universe;
  1767.         delete definitely_assigned_variables;
  1768.         delete definite_block_stack;
  1769.         delete definite_try_stack;
  1770.         delete definite_final_assignment_stack;
  1771.         delete definite_visible_variables;
  1772.         delete possibly_assigned_finals;
  1773.     }
  1774.  
  1775.     return;
  1776. }
  1777.  
  1778.  
  1779. void Semantic::DefiniteConstructorBody(AstConstructorDeclaration *constructor_declaration, Tuple<VariableSymbol *> &finals)
  1780. {
  1781.     AstConstructorBlock *constructor_block = constructor_declaration -> constructor_body;
  1782.     AstBlock *block_body = constructor_block -> block;
  1783.  
  1784.     universe = new BitSet(block_body -> block_symbol -> max_variable_index + finals.Length(), BitSet::UNIVERSE);
  1785.     definite_block_stack = new DefiniteBlockStack(constructor_declaration -> constructor_symbol -> max_block_depth,
  1786.                                                   universe -> Size());
  1787.     definite_try_stack = new DefiniteTryStack(constructor_declaration -> constructor_symbol -> max_block_depth);
  1788.     definite_final_assignment_stack =  new DefiniteFinalAssignmentStack();
  1789.     definite_visible_variables = new SymbolSet(universe -> Size());
  1790.     definitely_assigned_variables = new BitSet(universe -> Size(), BitSet::EMPTY);
  1791.     possibly_assigned_finals = new BitSet(universe -> Size(), BitSet::EMPTY);
  1792.     for (int i = 0; i < finals.Length(); i++)
  1793.     {
  1794.         int index = block_body -> block_symbol -> max_variable_index + i;
  1795.  
  1796.         finals[i] -> SetLocalVariableIndex(index);
  1797.         if (finals[i] -> IsDefinitelyAssigned())
  1798.         {
  1799.             definitely_assigned_variables -> AddElement(index);
  1800.             possibly_assigned_finals -> AddElement(index);
  1801.         }
  1802.         else if (finals[i] -> IsPossiblyAssigned())
  1803.             possibly_assigned_finals -> AddElement(index);
  1804.         definite_visible_variables -> AddElement(finals[i]);
  1805.     }
  1806.  
  1807.     //
  1808.     // As an explicit constructor call cannot refer to any locally declared variables
  1809.     // other than formal parameters, no local variable can be assigned within it (other
  1810.     // than a formal parameter which is considered to have been assigned anyway). Therefore,
  1811.     // the following code is not necessary:
  1812.     //
  1813.     //    if (this_call)
  1814.     //         DefiniteThisCall(this_call);
  1815.     //    else if (super_call)
  1816.     //         DefiniteSuperCall(super_call);
  1817.     //
  1818.  
  1819.     definite_block_stack -> Push(block_body);
  1820.  
  1821.     AstMethodDeclarator *constructor_declarator = constructor_declaration -> constructor_declarator;
  1822.     for (int j = 0; j < constructor_declarator -> NumFormalParameters(); j++)
  1823.     {
  1824.         AstFormalParameter *parameter = constructor_declarator -> FormalParameter(j);
  1825.         definitely_assigned_variables -> AddElement(parameter -> parameter_symbol -> LocalVariableIndex());
  1826.         if (parameter -> parameter_symbol -> ACC_FINAL())
  1827.             possibly_assigned_finals -> AddElement(parameter -> parameter_symbol -> LocalVariableIndex());
  1828.         definite_visible_variables -> AddElement(parameter -> parameter_symbol);
  1829.     }
  1830.  
  1831.     for (int l = 0; l < block_body -> block_symbol -> NumVariableSymbols(); l++)
  1832.         definite_visible_variables -> AddElement(block_body -> block_symbol -> VariableSym(l));
  1833.  
  1834.     DefiniteBlockStatements(block_body);
  1835.  
  1836.  
  1837.     //
  1838.     // Compute the set of finals that has definitely been assigned in this constructor
  1839.     //
  1840.     BitSet &exit_set = definite_block_stack -> TopExitSet(*definitely_assigned_variables);
  1841.     for (int k = 0; k < finals.Length(); k++)
  1842.     {
  1843.         int index = block_body -> block_symbol -> max_variable_index + k;
  1844.         if (exit_set[index])
  1845.             finals[k] -> MarkDefinitelyAssigned();
  1846.     }
  1847.  
  1848.     definite_block_stack -> Pop();
  1849.  
  1850.     delete universe;
  1851.     delete definitely_assigned_variables;
  1852.     delete definite_block_stack;
  1853.     delete definite_try_stack;
  1854.     delete definite_final_assignment_stack;
  1855.     delete definite_visible_variables;
  1856.     delete possibly_assigned_finals;
  1857.  
  1858.     return;
  1859. }
  1860.  
  1861.  
  1862. void Semantic::DefiniteBlockInitializer(AstBlock *block_body, int stack_size, Tuple<VariableSymbol *> &finals)
  1863. {
  1864.     universe = new BitSet(block_body -> block_symbol -> max_variable_index + finals.Length(), BitSet::UNIVERSE);
  1865.     definite_block_stack = new DefiniteBlockStack(stack_size + 1, universe -> Size()); // +1 to simulate enclosing method block
  1866.     definite_try_stack = new DefiniteTryStack(stack_size + 1);
  1867.     definite_final_assignment_stack =  new DefiniteFinalAssignmentStack();
  1868.     definite_visible_variables = new SymbolSet(universe -> Size());
  1869.     definitely_assigned_variables = new BitSet(universe -> Size(), BitSet::EMPTY);
  1870.     possibly_assigned_finals = new BitSet(universe -> Size(), BitSet::EMPTY);
  1871.     for (int i = 0; i < finals.Length(); i++)
  1872.     {
  1873.         int index = block_body -> block_symbol -> max_variable_index + i;
  1874.  
  1875.         finals[i] -> SetLocalVariableIndex(index);
  1876.         if (finals[i] -> IsDefinitelyAssigned())
  1877.         {
  1878.             definitely_assigned_variables -> AddElement(index);
  1879.             possibly_assigned_finals -> AddElement(index);
  1880.         }
  1881.         else if (finals[i] -> IsPossiblyAssigned())
  1882.             possibly_assigned_finals -> AddElement(index);
  1883.         definite_visible_variables -> AddElement(finals[i]);
  1884.     }
  1885.  
  1886.     definite_block_stack -> Push(NULL); // No method available
  1887.     definite_block_stack -> Push(block_body);
  1888.  
  1889.     for (int j = 0; j < block_body -> block_symbol -> NumVariableSymbols(); j++)
  1890.         definite_visible_variables -> AddElement(block_body -> block_symbol -> VariableSym(j));
  1891.  
  1892.     DefiniteBlockStatements(block_body);
  1893.  
  1894.     //
  1895.     // For each final that has definitely been assigned a value in this block,
  1896.     // mark it appropriately.
  1897.     //
  1898.     BitSet &exit_set = definite_block_stack -> TopExitSet(*definitely_assigned_variables);
  1899.     for (int k = 0; k < finals.Length(); k++)
  1900.     {
  1901.         int index = block_body -> block_symbol -> max_variable_index + k;
  1902.         if (exit_set[index])
  1903.             finals[k] -> MarkDefinitelyAssigned();
  1904.     }
  1905.  
  1906.     //
  1907.     // For each final that may have possibly been assigned a value in this block,
  1908.     // mark it appropriately.
  1909.     //
  1910.     exit_set = definite_block_stack -> TopFinalExitSet(*possibly_assigned_finals);
  1911.     for (int l = 0; l < finals.Length(); l++)
  1912.     {
  1913.         int index = block_body -> block_symbol -> max_variable_index + l;
  1914.         if (exit_set[index])
  1915.             finals[l] -> MarkPossiblyAssigned();
  1916.     }
  1917.  
  1918.     definite_block_stack -> Pop();
  1919.     definite_block_stack -> Pop(); // remove NULL that was pushed to indicate that no method is available
  1920.  
  1921.     delete universe;
  1922.     delete definitely_assigned_variables;
  1923.     delete definite_block_stack;
  1924.     delete definite_try_stack;
  1925.     delete definite_final_assignment_stack;
  1926.     delete definite_visible_variables;
  1927.     delete possibly_assigned_finals;
  1928.  
  1929.     return;
  1930. }
  1931.  
  1932.  
  1933. void Semantic::DefiniteVariableInitializer(AstVariableDeclarator *variable_declarator, Tuple<VariableSymbol *> &finals)
  1934. {
  1935.     universe = new BitSet(finals.Length(), BitSet::UNIVERSE);
  1936.     definite_block_stack = NULL;
  1937.     definite_try_stack = NULL;
  1938.     definite_final_assignment_stack =  new DefiniteFinalAssignmentStack();
  1939.     definite_visible_variables = new SymbolSet(universe -> Size());
  1940.     definitely_assigned_variables = new BitSet(universe -> Size(), BitSet::EMPTY);
  1941.     possibly_assigned_finals = new BitSet(universe -> Size(), BitSet::EMPTY);
  1942.     for (int i = 0; i < finals.Length(); i++)
  1943.     {
  1944.         finals[i] -> SetLocalVariableIndex(i);
  1945.         if (finals[i] -> IsDefinitelyAssigned())
  1946.         {
  1947.             definitely_assigned_variables -> AddElement(i);
  1948.             possibly_assigned_finals -> AddElement(i);
  1949.         }
  1950.         else if (finals[i] -> IsPossiblyAssigned())
  1951.             possibly_assigned_finals -> AddElement(i);
  1952.         definite_visible_variables -> AddElement(finals[i]);
  1953.     }
  1954.  
  1955.     DefiniteVariableInitializer(variable_declarator);
  1956.     VariableSymbol *symbol = variable_declarator -> symbol;
  1957.     if (symbol -> ACC_FINAL())
  1958.         symbol -> MarkDefinitelyAssigned();
  1959.     //
  1960.     // Also, update any other finals that may have been initialized as
  1961.     // a side-effect in an assignment embedded within the initializer
  1962.     // expression.
  1963.     //
  1964.     BitSet &exit_set = *definitely_assigned_variables;
  1965.     for (int k = 0; k < finals.Length(); k++)
  1966.     {
  1967.         if (exit_set[k])
  1968.             finals[k] -> MarkDefinitelyAssigned();
  1969.     }
  1970.  
  1971.     delete universe;
  1972.     delete definitely_assigned_variables;
  1973.     delete definite_final_assignment_stack;
  1974.     delete definite_visible_variables;
  1975.     delete possibly_assigned_finals;
  1976.  
  1977.     return;
  1978. }
  1979.